package com.jmp.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jmp.api.dto.MessageDto;
import com.jmp.api.dto.ResultTemplateDate;
import com.jmp.api.dto.WxSubscribeDto;
import com.jmp.api.dto.WxSubscribeTypeEnum;
import com.jmp.api.service.CompanyAccountService;
import com.jmp.api.service.MessageWxService;
import com.jmp.api.service.WechatBaseService;
import com.jmp.wx.WxSubscribeUtil;
import lombok.extern.slf4j.Slf4j;
import one.stand.enums.LoginEnum;
import one.stand.mapper.UserLoginWxMapperExt;
import one.stand.mapper.WxFormIdMapperExt;
import one.stand.mapper.WxNoticeMapper;
import one.stand.model.CompanyAccount;
import one.stand.model.UserLoginWx;
import one.stand.model.WxFormId;
import one.stand.model.WxNoticeModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * @author cjr
 */
@Service
@Slf4j
public class MessageWxServiceImpl implements MessageWxService {

    @Autowired
    private CompanyAccountService companyAccountService;

    @Autowired
    private WxNoticeMapper wxNoticeMapper;
    @Autowired
    private WxFormIdMapperExt wxFormIdMapperExt;
    @Autowired
    private WechatBaseService wechatBaseService;
    @Autowired
    private UserLoginWxMapperExt userLoginWxMapperExt;

    @Override
    @Async("asyncServiceExecutor")
    public void sendTemplateWx(MessageDto messageDto) {
        log.info("sendTemplateWx: {}", com.alibaba.fastjson.JSON.toJSONString(messageDto));

//        User userModel = userAdminService.getByUserId(messageDto.getToUserId());
//        Integer companyId = Objects.nonNull(messageDto.getCompanyId()) ? messageDto.getCompanyId() : userModel.getEnterpriseId();

//        if (StringUtils.isNoneBlank(messageDto.getCompanyKey())) {

//        UserLoginWx userLoginWx = userLoginWxMapperExt.select(messageDto.getToUserId(), messageDto.getCompanyKey(), messageDto.getAccountType().getAccountType());
//        String touser = userLoginWx.getOpenId();
//        int formId_type = LoginEnum.CRM.equals(messageDto.getAccountType()) ? MessageApi.FORM_ID_TYPE_CRM : MessageApi.FORM_ID_TYPE_USER;
//        WxFormId wxFormId = wxFormIdMapperExt.selectByCompanyKey(messageDto.getToUserId(), formId_type, messageDto.getCompanyKey());
//        String formId = StringUtils.isNoneBlank(messageDto.getFormId()) ? messageDto.getFormId() : wxFormId.getFormId();
//        CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(wxFormId.getCompanyKey(), messageDto.getAccountType());
//        String accessToken = wechatBaseService.getWxToken(companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
//        log.info("模板推送-accessToken：{}", accessToken);
//        if (StringUtils.isBlank(accessToken)) {
//            log.error("access token null");
//            return;
//        }
//        WxNoticeModel model = wxNoticeMapper.select(new WxNoticeModel() {{
//            setCompanyId(companyAccountModel.getCompanyId());
//            setCode(messageDto.getNoticeEnums().getCode());
//        }});
//        if (model == null) {
//            log.error("notice (companyId={},code={}) is null", companyId, messageDto.getNoticeEnums());
//            return;
//        }
//        send(model, accessToken, touser, messageDto.getParameter(), formId, messageDto.getFillData());
//        } else {
//            String touser = LoginEnum.CRM.equals(messageDto.getAccountType()) ? userModel.getCrmOpenId() : userModel.getOpenId();
//            WxFormId wxFormId = wxFormIdMapperExt.select(messageDto.getToUserId(), LoginEnum.CRM.equals(messageDto.getAccountType()) ? MessageApi.FORM_ID_TYPE_CRM : MessageApi.FORM_ID_TYPE_USER);
//            String formId = StringUtils.isNoneBlank(messageDto.getFormId()) ? messageDto.getFormId() : wxFormId.getFormId();
//            AssertUtil.nonNull(formId, "formid is null");
//
//            User user = null;
//            if (messageDto.getAccountType().equals(LoginEnum.CRM)) {
//                user = userAdminService.getByCrmOpenId(touser);
//            } else if (messageDto.getAccountType().equals(LoginEnum.USER)) {
//                user = userAdminService.getByUserOpenId(touser);
//            }
//            AssertUtil.nonNull(user, ResultEnum.PARAM_CHECK, "用户不存在");
//            CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(user.getEnterpriseId(), messageDto.getAccountType());
//            String accessToken = wechatBaseService.getWxToken(companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
//            log.info("模板推送-accessToken：{}", accessToken);
//            if (StringUtils.isBlank(accessToken)) {
//                log.error("access token null");
//                return;
//            }
//            WxNoticeModel model = wxNoticeMapper.select(new WxNoticeModel() {{
//                setCompanyId(companyId);
//                setCode(messageDto.getNoticeEnums().getCode());
//            }});
//            if (model == null) {
//                log.error("notice (companyId={},code={}) is null", companyId, messageDto.getNoticeEnums());
//                return;
//            }
//
//            send(model, accessToken, touser, messageDto.getParameter(), formId, messageDto.getFillData());
//        }
    }

    @Override
    public void saveFormId(Integer userId, Integer type, String formId, String companyKey) {
        WxFormId wxFormId = new WxFormId();
        wxFormId.setUserId(userId);
        wxFormId.setType(type);
        wxFormId.setFormId(formId);
        wxFormId.setCompanyKey(companyKey);
        wxFormIdMapperExt.insertSelective(wxFormId);

        wxFormIdMapperExt.deleteByFormId("");//清除无用formId
    }

    /**
     * 微信订阅消息
     */
    @Override
    @Async("asyncServiceExecutor")
    public void wxSubscribe(WxSubscribeDto subscribeDto) {
        String companyKey = "huayuan";
        UserLoginWx userLoginWx = userLoginWxMapperExt.select(subscribeDto.getToId(), companyKey, LoginEnum.USER.getAccountType());
        subscribeDto.setTouser(userLoginWx.getOpenId());
        CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(companyKey, LoginEnum.USER);
        subscribeDto.setAccessToken(wechatBaseService.getWxToken(companyAccountModel.getAppId(), companyAccountModel.getAppSecret()));

        WxSubscribeTypeEnum typeEnum = WxSubscribeTypeEnum.getById(subscribeDto.getType());
        WxSubscribeUtil.send(typeEnum, subscribeDto);
    }

    private void send(WxNoticeModel model, String accessToken, String touser, String parameter, String formId, String[] fillData) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + accessToken);
        // 装配post请求参数
        JSONObject json = new JSONObject();
        json.put("touser", touser);
        json.put("template_id", model.getValue());
        if (StringUtils.isBlank(parameter)) {
            json.put("page", model.getPage());
        } else {
            json.put("page", model.getPage() + parameter);
        }
        json.put("form_id", formId);
        JSONObject dataJson = new JSONObject();
        for (int i = 0; i < fillData.length; i++) {
            JSONObject sonDateJson = new JSONObject();
            sonDateJson.put("value", fillData[i]);
            dataJson.put("keyword" + (i + 1), sonDateJson);
        }
        json.put("data", dataJson);
        String resultStr = "发送失败";
        try {
            StringEntity myEntity = new StringEntity(json.toJSONString(), ContentType.APPLICATION_JSON);
            // 设置post求情参数
            httpPost.setEntity(myEntity);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                // 发送成功
                String resutlEntity = EntityUtils.toString(httpResponse.getEntity());
                log.info("推送结果：{}", resutlEntity);

                ResultTemplateDate resultTemplateDate = JSONObject.parseObject(resutlEntity, ResultTemplateDate.class);
                if ("40037".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "template_id不正确";
                }
                if ("41028".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "form_id不正确，或者过期";
                }
                if ("41029".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "form_id已被使用";
                }
                if ("41030".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "page不正确";
                }
                if ("45009".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "接口调用超过限额（目前默认每个帐号日调用限额为100万）";
                }
                if ("0".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "成功";
                }
                log.info("本次微信推送模板推送结果：{} {}", resultTemplateDate.getErrcode(), resultStr);
            } else {
                log.info("本次微信推送模板推送结果：发送失败 {}", httpResponse.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (httpClient != null) {
                    // 释放资源
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            wxFormIdMapperExt.deleteByFormId(formId);
        }
    }
}
